import 'package:get/get.dart';
import 'package:largefriends/entity/entities/lf_bool_entity.dart';
import 'package:largefriends/entity/entities/lf_photo_entity.dart';
import 'package:largefriends/net/lf_image_upload.dart';
import 'package:largefriends/utils/lf_dialog_utils.dart';

import '../../../../config/lf_route.dart';
import '../../../../net/error_handle.dart';
import '../../../../net/lf_api_url.dart';
import '../../../../net/lf_dio_util.dart';
import '../../../../res/strings/lf_strings.dart';
import '../../../../service/lf_auth_service.dart';
import '../../../../widgets/dialog_action_tip.dart';
import '../../../../widgets/lf_image_picker.dart';
import '../../../../widgets/preload_page_view.dart';
import '../../../../widgets/dialog_action_sheet.dart';

toManagePhotoGallery({required int index}) {
  Get.toNamed(LFRoute.pathManagePhotoGallery, arguments: {'index': index});
}

class LfManagePhotoGalleryLogic extends GetxController {
  late PreloadPageController controller;
  RxInt currentIndex = 0.obs;
  List<LfPhotoEntity> photos = List.empty(growable: true);
  LfAuthService authService = Get.find();

  @override
  void onInit() {
    photos.addAll(authService.currentAccount!.publicPhotos());
    photos.addAll(authService.currentAccount!.privatePhotos());
    currentIndex.value = Get.arguments['index'];
    controller = PreloadPageController(initialPage: currentIndex.value);
    super.onInit();
  }

  @override
  void onClose() {
    controller.dispose();
    super.onClose();
  }

  void showMoreAction() {
    if (currentIndex.value >= photos.length) {
      return;
    }
    var photo = photos[currentIndex.value];
    List<ActionSheetItem> actions = List.empty(growable: true);
    if (photo.type == photoTypePublic) {
      if (photo.avatar) {
        actions.add(ActionSheetItem(
            action: () {
              _updateMain();
            },
            title: strUpdatePhoto.tr));
      } else {
        actions.add(ActionSheetItem(
            action: () {
              _setAsMain(photo);
            },
            title: strSetItAsMain.tr));
        actions.add(ActionSheetItem(
            action: () {
              _changePhotoType(photo);
            },
            title: strMakePrivate.tr));
        actions.add(ActionSheetItem(
            action: () {
              _deletePhoto(photo);
            },
            title: strDelete.tr));
      }
    } else {
      actions.add(ActionSheetItem(
          action: () {
            _changePhotoType(photo);
          },
          title: strMakePublic.tr));
      actions.add(ActionSheetItem(
          action: () {
            _deletePhoto(photo);
          },
          title: strDelete.tr));
    }
    showActionSheet(actions: actions);
  }

  _deletePhoto(LfPhotoEntity entity) {
    showActionTips(
        tips: strDeletePhotoTip.tr,
        actionButtonTip: strSure.tr,
        action: () {
          _deletePhotoAction(entity);
        });
  }

  _deletePhotoAction(LfPhotoEntity entity) {
    showLoading();
    LfDio.instance.post<LfBoolEntity>(
      url: apiDeletePhoto,
      params: {'attachId': entity.attachId},
    ).then((value) {
      photos.removeWhere((element) => element.attachId == entity.attachId);
      if (currentIndex.value >= photos.length) {
        currentIndex.value = photos.length - 1;
      }
      controller.jumpToPage(currentIndex.value);
      if (entity.type == photoTypePublic) {
        authService.currentAccount!
            .publicPhotos()
            .removeWhere((element) => element.attachId == entity.attachId);
        authService.setUserEntity(authService.currentAccount);
      } else {
        authService.currentAccount!
            .privatePhotos()
            .removeWhere((element) => element.attachId == entity.attachId);
        authService.setUserEntity(authService.currentAccount);
      }
      hideLoading();
      update();
    }, onError: (error) {
      hideLoading();
      if (error is NetError) {
        showSnackBar(error.msg);
      }
    });
  }

  _changePhotoType(LfPhotoEntity entity) {
    showActionTips(
        tips: entity.type == photoTypePublic
            ? strMovePhotoToPrivateTip.tr
            : strMovePhotoToPublicTip.tr,
        actionButtonTip: strYes.tr,
        action: () {
          _changePhotoTypeAction(entity);
        });
  }

  _changePhotoTypeAction(LfPhotoEntity entity) {
    showLoading();
    LfDio.instance.post<LfBoolEntity>(url: apiChangePhotoType, params: {
      'attachId': entity.attachId,
      'photoType':
          entity.type == photoTypePublic ? photoTypePrivate : photoTypePublic
    }).then((value) {
      if (entity.type == photoTypePublic) {
        entity.type = photoTypePrivate;
        authService.currentAccount!
            .publicPhotos()
            .removeWhere((element) => element.attachId == entity.attachId);
        authService.currentAccount!.privatePhotos().add(entity);
      } else {
        entity.type = photoTypePublic;
        entity.status = 0;

        ///私有变公有,需要pending
        authService.currentAccount!
            .privatePhotos()
            .removeWhere((element) => element.attachId == entity.attachId);
        authService.currentAccount!.publicPhotos().add(entity);
      }
      authService.setUserEntity(authService.currentAccount!);
      photos.clear();
      photos.addAll(authService.currentAccount!.publicPhotos());
      photos.addAll(authService.currentAccount!.privatePhotos());
      hideLoading();
      update();
    }, onError: (error) {
      hideLoading();
      if (error is NetError) {
        showSnackBar(error.msg);
      }
    });
  }

  void _setAsMain(LfPhotoEntity photo) {
    showLoading();
    LfDio.instance.post<LfBoolEntity>(
        url: apiChangeAvatar,
        params: {'attachId': photo.attachId}).then((value) {
      authService.currentAccount!
          .publicPhotos()
          .removeWhere((element) => element.attachId == photo.attachId);

      ///移除刚才的那个照片
      for (var element in authService.currentAccount!.publicPhotos()) {
        ///将原本头像设置为非头像
        if (element.avatar) {
          element.avatar = false;
        }
      }
      photo.avatar = true; //将改照片设置为头像
      authService.currentAccount!.publicPhotos().insert(0, photo);
      authService.currentAccount!.avatar = photo.url;
      authService.setUserEntity(authService.currentAccount!);
      photos.clear();
      photos.addAll(authService.currentAccount!.publicPhotos());
      photos.addAll(authService.currentAccount!.privatePhotos());
      hideLoading();
      update();
    }, onError: (error) {
      hideLoading();
      if (error is NetError) {
        showSnackBar(error.msg);
      }
    });
  }

  void _updateMain() {
    LfImagePicker.pickerImage(
      (result) async {
        if (result.isNotEmpty) {
          showLoading();
          await uploadPicture(fileList: [result.first], type: photoTypePublic)
              .then((attaches) {
            if (attaches.isEmpty) {
              hideLoading();
              return;
            }
            LfDio.instance.post<LfBoolEntity>(
                url: apiChangeAvatar,
                params: {'attachId': attaches.first.attachId}).then((value) {
              for (var element in authService.currentAccount!.publicPhotos()) {
                ///将原本头像设置为非头像
                if (element.avatar) {
                  element.avatar = false;
                }
              }
              attaches.first.status = 0;
              attaches.first.avatar = true; //将改照片设置为头像
              authService.currentAccount!
                  .publicPhotos()
                  .insert(0, attaches.first);
              authService.currentAccount!.avatar = attaches.first.url;
              authService.setUserEntity(authService.currentAccount!);
              photos.clear();
              photos.addAll(authService.currentAccount!.publicPhotos());
              photos.addAll(authService.currentAccount!.privatePhotos());
              hideLoading();
              update();
            }, onError: (error) {
              hideLoading();
              if (error is NetError) {
                showSnackBar(error.msg);
              }
            });
          }, onError: (error) {
            hideLoading();
            if (error is NetError) {
              showSnackBar(error.msg);
            }
          });
        }
      },
      maxCount: 1,
    );
  }
}
